package com.pan.common.interview.jvm;

/**
 * @author by panstark
 * @description
 * @notice
 * @date 2020/12/24
 */
public class ClassLoaderInfo {


    /**
     *Classloader在java中十分重要，它主要工作在Class装载的加载阶段，
     * 从系统外部获取class二进制流，交给java虚拟就进行链接、初始化。
     */

    /**
     * ClassLoader的种类
     * BootStrapClassLoader：C++编写，加载核心类库java.*
     * ExtClassLoader:Java编写，加载扩展类库javax.*
     * AppClassLoader:Java编写，加载程序所在目录（即自己编写的程序）
     * 自定义ClassLoader：Java编写，定制化加载
     */

    /**
     * 自定义ClassLoader的实现
     * 关键函数
     * protected Class<?> findClass(String className) throws ClassNotFoundException{
     *     throw new ClassNotFoundException();
     * }
     *
     * protected final Class<?> defineClass(int[]  byte,int off, int len) throws ClassFormatError{
     *
     * return defineClass(null,b,off,len,null);
     * }
     */

    /**
     * 双亲委派机制
     * 自底向上检查类是否已经加载
     *  顺序： 自定义ClassLoader-->AppClassLoader-->ExtClassLoader-->BootStrapClassLoader
     * 自顶向下尝试加载类
     * 顺序 ：BootStrapClassLoader-->load jre\lib\rt.jar 或者 -Xbootclasspath选项指定的jar包
     *       ExtClassLoader-->Load jre\lib\ext\*.jar 或者 Djava.ext.dirs指定目录下的jar包
     *       AppClassLoader-->Load CLASSPATH或Djava.class.path所指定的目录下的类和jar包
     *       自定义ClassLoader-->  通过java.lang.ClassLoader的子类自定义加载class
     *
     */

    /**
     * 为什么使用双亲委派机制
     * 避免多份同样字节码的加载
     */

    /**
     * 类的加载方式
     * 隐式加载 new
     * 显式加载 loadClass ，class.ForName
     */

    /**
     * 类装载过程：
     * 加载：通过ClassLoader加载class文件字节码，生成Class对象
     * 链接：
     *    a/校验：检查加载class类的准确性和安全性
     *    b/准备：为类变量分配存储空间并设置类变量初始值（类变量，就是static变量）
     *    c/解析：JVM将常量池的符号引用，改为直接饮用。
     * 初始化：执行类变量赋值和静态代码块
     *
     * class.ForName：得到的class是已经完成初始化的
     * ClassLoader.loadClass得到的class还是没有链接的
     */

}
